<?
/**
* @copyright (C) 2005 - 2008 SystN International Pty Ltd.
* @license http://www.SystN.com
* SystN is Free Software
*/

//驱动处理
class DBSQL{
  
	/**
	*  处理数据库载入单元
	*/
	function DBSQL($DBA=''){
		
		//服务器检测
		if(eregi('mysql',$DBA['dbtype']) || eregi('mssql',$DBA['dbtype'])){
			$func_name   = $DBA['dbtype'].'_connect';
		}elseif(eregi('sqlite',$DBA['dbtype'])) {
			$func_name = 'sqlite_open';
			$this->error = $DBA['dbtype'];
		}elseif(eregi('pgsql',$DBA['dbtype'])) {
			$func_name = 'pg_connect';
			$this->error = $DBA['dbtype'];
		}else{
			die('抱歉，Drive Link 不支持此类型数据库!');
		}
		
		//当前数据库类型
		$this->dbtype = $DBA['dbtype'];
		
		if (!function_exists($func_name)){
			die('您的服务器不支持'.$DBA['dbtype'].'数据链。');
		}
		
		//错误机制处理
		$this->error = strtolower($DBA['dbtype']);
		
		//引入驱动
		if(!is_file(dirname(__FILE__)."/".$DBA['dbtype'].".php")){
			die('Fail to load database '.$DBA['dbtype']);
		}
		include_once dirname(__FILE__)."/".$DBA['dbtype'].".php";
		//声明驱动单元
		$this -> DB = new Dirver;
		$this -> DB -> DBLink($DBA);
	}
	
	
	/**
	*  返回数组资料行
	*/
	function rows($query) {
		return $this->fetch_array($this->query($query));
	}
	
	
	/**
	*  返回数组行
	*/
	function nums($query) {
		return $this->num_rows($this->query($query));
	}
	
	
	/**
	*  一个查询字符串
	*  limit大于0则表示限制数据集，小于0则禁止错误调试
	*/
	function query($sql,$limit=''){
		$limit = (int)$limit;
		$query = $this -> DB -> query($sql,$limit);
		if(!$query && $limit>=0){
			$this->error($sql);
		}
		return $query;
	}
	
	
	/**
	*  取得返回列的数目
	*/
	function num_rows($query) {
		return $this -> DB -> num_rows($query);
	}
	
	
	/**
	*  返回数组资料
	*/
	function fetch_array($query){
		return $this -> DB -> fetch_array($query);
	}
	
	
	/**
	*  返回数组资料
	*/
	function list_array($info){
		if($info['query'] && trim($info['seek'])){
			mssql_data_seek($info['query'],$info['seek']);
			return $this -> DB -> fetch_array($info['query']);
		}else{
			return $this -> DB -> fetch_array($info['query']);
		}
	}
	
	
	/**
	*  返回最后一次插入指令的 ID
	*/
	function insert_id(){
		return $this -> DB -> insert_id();
	}
	
	
	/**
	*  关闭当前数据库连接
	*/
	function close(){
		return $this -> DB -> close();
	}
	
	
	/**
	*  检测数据库版本
	*/
	function version(){
		return $this -> DB -> version();
	}
	
	
	/**
	*  分页预处理函数
	*  sql		SQL语句
	*  page		当前页数
	*  limit	每页显示的数量
	*  maxs		查询总数
	*/
	function limit($sql,$page='0',$limit=10,$maxs=''){
		$show = Array();
		$page = (trim($page)>0)?$page:1;
		$limit = (trim($limit)>0)?$limit:1;
		
		//信息数
		if(trim($maxs)==''){
			$order	= preg_replace("/.+(order by.+)/is","\\1",$sql);
			if(eregi('order by',$order)){
				$sqls	= str_replace($order,"",$sql);
			}else{
				$order	= '';
				$sqls	= $sql;
			}
			
			$counts = $this -> fetch_array($this -> query( preg_replace("/SELECT.+FROM(.+?)/is","SELECT COUNT(*) AS cnt FROM ",$sqls)) );
			$Alls	= $counts['cnt'];
		}else{
			$Alls = $maxs;
		}
		
		
		$MaxPages	= (int)ceil($Alls/$limit);							//处理分了几页
		$QuerySeek	= (($page > $MaxPages)? $MaxPages-1: $page-1)*$limit;	//数据查询指针数
		
		switch($this->dbtype){
			case'mssql':
				
				//ID
				$id  = @mssql_fetch_array(mssql_query("SELECT name FROM syscolumns WHERE id=object_id(N'users') AND COLUMNPROPERTY(id,name,'IsIdentity')=1"));
				
				$sql = preg_replace('/^SELECT\s/i', 'SELECT TOP '.$limit.' ', $sqls);
				//判断where 
				if(eregi('WHERE',$sql)){
					$sql	= preg_replace("/WHERE/i","WHERE",$sql);
					$sql	= preg_replace('/FROM\s([a-z0-9_]+)/i', "FROM \\1 [W] ".$id['name']." NOT IN (SELECT TOP ".$QuerySeek." ".$id['name']." FROM \\1 order by ".$id['name'].") [W]", $sql);
					$wtop	= preg_replace('/.+\[W\](.+)\[W\].+/i', "\\1", $sql);
					$sql	= str_replace('[W]'.$wtop.'[W]', "",$sql);
					//还原数据
					$sql	= str_replace('WHERE', "WHERE $wtop AND",$sql);
					
				}else{
					$sql = preg_replace('/FROM\s([a-z0-9_]+)/i', "FROM \\1 WHERE ".$id['name']." NOT IN (SELECT TOP ".$QuerySeek." ".$id['name']." FROM \\1 order by ".$id['name'].") ", $sql);
					//其他处理
					$ot1 = preg_replace('/.+(WHERE.+\)).+/i', "\\1", $sql);
					$sql = str_replace($ot1,"",$sql).' '.$ot1;
				}
				
				$query	= $sql.' '.$order;
			break;
				
			case'pgsql':
				$query	= "$sql LIMIT $limit OFFSET ".$QuerySeek;
			break;
			
			default:
				$query	= "$sql LIMIT ".$QuerySeek.",$limit";
		}
		
		$show['query']	= $this -> query($query);			//执行语句
		
		$show['info']	= array(
						"limit"		=> $limit,				//每页的分页数
						"nowlimit" 	=> count($show),		//列出当前的信息数
						"nowpage"	=> ($page > $MaxPages)? $MaxPages:$page,
						"pages"		=> $MaxPages,			//分了几页
						"nums"		=> $Alls,				//当前查询中最大信息数
						);
		return $show;
	}
	
	
	/**
	*  显示数据库查询类别
	*/
	function sql_num(){
		return (int)$this -> DB -> sql_num();
	}
	
	
	/**
	*  显示详细的SQL语句
	*/
	function sql_debug(){
		return $this -> color($this -> DB -> sql_debug());
	}
	
	
	/**
	*  SQL语句色彩处理
	*/
	function color($show){
			$show = preg_replace('/(\(|\)|\'|")/is', '<b>\\1</b>', $show);
			$show = preg_replace('/\'(.+?)\'/is', '\'<font color=#800000x>\\1</font>\'', $show);
			//对AND还有OR进行更改颜色
			$show = preg_replace( "#\s{1,}(AND|OR)\s{1,}#i", " <font color='dodgerblue'>\\1</font> "    , $show );
			//数据表的名字
			$show = preg_replace( "#(FROM|INTO|UPDATE)\s{1,}(\S+?)\s{1,}#is", "\\1<font color='#8899DF'>&nbsp;<b><u>\\2</u></b>&nbsp;</font>" , $show);
			//每行下增加一个分割线
			$show = str_replace('<br>', "<br><hr size='1' width='85%' align='left' color='navyblue'>", $show);
			//选择数据库
			$show = str_replace('SELECT', '<font color=darkslateblue><b><u>SELECT</u></b></font>', $show);
			//更新数据库
			$show = str_replace('UPDATE', '<font color="deepskyblue"><b><u>UPDATE</u></b></font>', $show);
			//删除数据库
			$show = str_replace('DELETE', '<font color="red"><b><u>DELETE</u></b></font>', $show);
			//插入数据库
			$show = str_replace('INSERT', '<font color="limegreen"><b><u>INSERT</u></b></font>', $show);
			$show = str_replace('LEFT JOIN', '<font color="salmon"><b>LEFT JOIN</b></font>', $show);
			$show = preg_replace( "/(INTO|FROM)/is", '<font color="#18A3F5"><b>\\1</b></font>' , $show );
			$show = str_replace('WHERE', '<font color="slategray"><b>WHERE</b></font>', $show);
			$show = str_replace('ORDER BY', '<font color="slategray"><b>ORDER BY</b></font>', $show);
			$show = str_replace('VALUES', '<font color="olivedrab">VALUES</font>', $show);
			$show = str_replace('SET', '<font color="#009933">SET</font>', $show);
		return $show;
	}
	
	
	/**
	*  错误处理机制
	*/
	function error($sql=''){
		include_once dirname(__FILE__).'/error.php';
		new DB_Error($this->color($sql),$this->error);
	}
}
?>